package makeeasier.utils 
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	/**
	$(CBI)* ...
	$(CBI)* @author Akinon
	$(CBI)*/
	public class QueueSystem extends EventDispatcher
	{
		/*
		 * miliseconds
		 * */
		private var _interval:Number;
		
		/*
		 * job count will be called on per tick
		 * */
		private var _jobsPerInterval:int;
		
		/*
		 * jobList
		 * */
		private var jobList:Vector.<Function>;
		
		/*
		 * job timer
		 * */
		private var timer:Timer;
		
		
		
		public function QueueSystem() 
		{
			_interval = 1000;
			_jobsPerInterval = 50;
			timer = new Timer(_interval);
			jobList = new Vector.<Function>();
		}
		
		/*
		 * start queue
		 * */
		public function start():void
		{
			timer = new Timer(_interval);
			timer.addEventListener(TimerEvent.TIMER, intervalTick);
			timer.start();
		}
		
		/*
		 * stop queue
		 * */
		public function stop():void
		{
			timer.stop();
			timer = null;
		}
		
		private function intervalTick(e:TimerEvent):void
		{
			var limit:int = _jobsPerInterval < jobList.length ? _jobsPerInterval : jobList.length;
			if ( limit == 0 ) {
				return;
			}
			for (var i:int = 0; i < limit; i++) 
			{
				jobList[i].call();
			}
			jobList.splice(0, limit);
			/*
			if (jobList.length == 0) {
				stop();
				dispatchEvent(new Event(Event.COMPLETE));
				return;
			}
			*/
		}
		
		/*
		 * adding new jobs
		 * */
		public function addJob(fx:Function):void
		{
			jobList.push(fx);
		}
		
		/*
		 * removing jobs from queue
		 * */
		public function removeJob(fx:Function):void
		{
			jobList.splice(jobList.indexOf(fx),1);
		}
		
		public function get interval():Number { return _interval; }
		
		public function set interval(value:Number):void 
		{
			if ( timer.running ) {
				throw new Error("Runtime error: Pooling interval cannot change while jobs are working");
				return;
			}
			timer = new Timer(_interval);
			_interval = value;
		}
		
		public function get jobsPerInterval():int { return _jobsPerInterval; }
		
		public function set jobsPerInterval(value:int):void 
		{
			if ( timer.running ) {
				throw new Error("Runtime error: Pooling interval cannot change while jobs are working");
				return;
			}
			_jobsPerInterval = value;
		}
		
		/*
		 * returns queue
		 * */
		public function getQueue():Vector.<Function>
		{
			return jobList;
		}
		
	}

}